package net.esj.basic.pojo;

import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import net.esj.basic.annotation.IgnorePrint;

import org.springframework.beans.BeanUtils;


public abstract class AbstractPojo<ID extends Serializable> implements PrimaryKey<ID> {

	/**
	 * 
	 */
	private static final long serialVersionUID = -4536444335416801439L;

	public static final String POJO_FIELD_TITLE_POSTFIX = ".title";
	
	public static final String POJO_FIELD_COMMENTS_POSTFIX = ".title";
	
	protected UpdateType updateType = UpdateType.AUTO;
	
	protected Updater updater =new Updater();
	
	protected boolean autoNotifyUpdate = false;
	
	private Map<String,Object> loadedStates = new HashMap<String,Object>();
	
	public AbstractPojo self = null;
	public Class<?> pojoClass = null;
	
	public void notifyUpdater(String... args){
		updater.notify(args);
		updateType = UpdateType.BY_UPDATER;
	}

	@IgnorePrint
	public Updater getUpdater() {
		return updater;
	}
	
	public AbstractPojo setUpdateType(UpdateType type){
		this.updateType = type;
		return this;
	}

	@IgnorePrint
	public UpdateType getUpdateType() {
		return updateType;
	}
	
	protected void autoNotify(PropertyDescriptor pd){
		if(isAutoNotify()){
			String name = pd.getDisplayName();
			notifyUpdater(name);
		}
	}
	
	@IgnorePrint
	private boolean isAutoNotify(){
		return updateType == UpdateType.BY_UPDATER
			&& autoNotifyUpdate;
	}
	
	/**
	 * 是否需要对实体做冗余操作
	 * @return
	 */
	public boolean needRedundant(){
		return true;
	}
	
	public void loadedStates(String propertyName,Object state){
		loadedStates.put(propertyName, state);
	}
	
	@Deprecated
	public static class SetMethodHandler implements InvocationHandler{

		
		
		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			Object val = method.invoke(proxy, args);
			if(proxy instanceof AbstractPojo 
					&& method.getName().startsWith("set")){
				PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
				if(pd!=null){
					((AbstractPojo)proxy).autoNotify(pd);
				}
			}
			return val;
		}

	}
}
